#include "Console.h"


Console::Console(Client* client): cliente(client) {
	this->terminateExecution = false;
}

void Console::show_shell() {

	std::cout << std::endl;
	std::cout << PROMPT;
	std::string operation= "";
	std::getline(std::cin, operation);
	std::string function= get_function(operation);

	if((function.compare(HELP_SHORT)) == 0 || (function.compare(HELP_LONG)) == 0)
		show_help();
	else if((function.compare(VERSION_SHORT)) == 0 || (function.compare(VERSION_LONG)) == 0)
		show_version();
	else if((function.compare(INSERT_SHORT)) == 0 || (function.compare(INSERT_LONG)) == 0)
		insert_register(operation);
	else if((function.compare(REMOVE_SHORT)) == 0 || (function.compare(REMOVE_LONG)) == 0)
		remove_register(operation);
	else if((function.compare(UPDATE_SHORT)) == 0 || (function.compare(UPDATE_LONG)) == 0)
		update_register(operation);
	else if((function.compare(GET_SHORT)) == 0 || (function.compare(GET_LONG)) == 0)
		get_register(operation);
	else if((function.compare(QUIT_SHORT)) == 0 || (function.compare(QUIT_LONG)) == 0)
		doQuit();
	else
		show_error("La opcion elegida no existe.");
}



void Console::show_inicio() {
	std::cout << "()()  #################################################" << std::endl;
	std::cout << "(..) (``•.¸(``•.¸(``•.¸(``•.¸ ¸.•`´)¸.•`´)¸.•`´)¸.•`´)" << std::endl;
	std::cout << "C()() «´¨¸¸¸¸[ -~~~~~~~~~ CONCU-DB ~~~~~~~~~-]¸¸¸¸¨`» ()*()" << std::endl;
	std::cout << "      (¸.•`´(¸.•`´(¸.•`´(¸.•`´ ``•.¸)``•.¸)``•.¸)``•.¸) (*'.')" << std::endl;
	std::cout << "      ################################################# (/(o)(o)..." << std::endl;
	std::cout << std::endl;
}

void Console::show_help() {
	std::cout << "Usos: " << std::endl;
	std::cout << "Opciones:" << std::endl;
	std::cout << "  -h,   --help      Imprime la informacion de uso." << std::endl;
	std::cout << "  -v,   --version   Imprime la version del programa." << std::endl;
	std::cout << "  -i,   --insert    Inserta un registro." << std::endl;
	std::cout << "  -r,   --remove    Borra un registro." << std::endl;
	std::cout << "  -g,   --get   	  Muestra un registro" << std::endl;
	std::cout << "  -u,   --update    Actualiza un registro" << std::endl;
	std::cout << "  -q,   --quit      Salir del programa." << std::endl;
	std::cout << std::endl;
	std::cout << "  Los campos de los registros se separan con : " << std::endl;
}

void Console::show_version() {
	std::cout << "CONCUDB 1.0" << std::endl;
	std::cout << "Copyright (C) 2011 Free Software Foundation, Inc." << std::endl;
	std::cout << "Writen by Veronica Bukaczewski, Lucia Garbarini y Matias De Antoni." << std::endl;
}


void Console::insert_register(std::string &operation){
	DBRegister *registro= 	this->parseRegister(operation);
	if ( registro !=  NULL ) {
		std::cout<<"-- Insertar registro"<<std::endl;
		registro->print();
		int result = cliente->insertRegister(registro);
		if ( result == result_ok )
			std::cout<<"-- Registro insertado correctamente"<<std::endl;
		else if ( result == result_server_error )
			std::cout<<"-- Error al conectar con el servidor"<<std::endl;
		else if ( result == result_exists )
			std::cout<<"-- El registro ya existe en la base de datos"<<std::endl;
		else
			std::cout<<"-- Error al intentar insertar el registro"<<std::endl;

		delete registro;
	}
}

void Console::get_register(std::string &operation){
	DBRegister registro;
	std::size_t final_pos= operation.find(SPACE);
	std::string primaryKey = std::string(operation, final_pos +1 , operation.size());
	std::cout<<"-- Obtener registro: "<< primaryKey <<std::endl;
	int result = cliente->getRegister(primaryKey,&registro);
	if ( result == result_ok ) {
		std::cout << "-- El registro obtenido fue : " <<std::endl;
		registro.print();
	}
	else if ( result == result_server_error ) {
		std::cout<<"-- Error al conectar con el servidor"<<std::endl;
	}
	else{
		std::cout<<"-- Error al intentar obtener el registro"<<std::endl;
	}

}

void Console::remove_register(std::string &operation){
	std::size_t final_pos= operation.find(SPACE);
	std::string primaryKey = std::string(operation, final_pos +1 , operation.size());
	DBRegister registro(primaryKey.c_str(),"","");
	std::cout<<"-- Remover registro"<<std::endl;
	registro.print();
	int result = cliente->removeRegister(&registro);
	if ( result == result_ok )
		std::cout<<"-- Registro removido correctamente"<<std::endl;
	else if ( result == result_server_error )
		std::cout<<"-- Error al conectar con el servidor"<<std::endl;
	else
		std::cout<<"-- Error al intentar remover el registro"<<std::endl;

}

void Console::update_register(std::string &operation){
	DBRegister *registro= 	this->parseRegister(operation);
	if ( registro !=  NULL ) {

		std::cout<<"-- Actualizar registro"<<std::endl;
		registro->print();
		int result = cliente->updateRegister(registro);
		if ( result == result_ok )
			std::cout<<"-- Registro actualizado correctamente"<<std::endl;
		else if ( result == result_server_error )
			std::cout<<"-- Error al conectar con el servidor"<<std::endl;
		else
			std::cout<<"-- Error al intentar actualizar el registro"<<std::endl;
		delete registro;
	}
}



void Console::show_error(const std::string& error_message) {
	std::cout << "-- " << error_message << " --" << std::endl;
	show_help();
}

void Console::show_bye() {
	std::cout << "############################# GOOD-BYE #############################" << std::endl;
}

void Console::doQuit() {
	this->terminateExecution = true;
}

std::string Console::get_function(std::string &operation) {
	std::size_t final_pos= operation.find(SPACE);
	return std::string(operation, 0, final_pos);
}


void Console::show_waiting() {
	std::cout << "Waiting..." << std::endl;
}

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
	 std::stringstream ss(s);
	 std::string item;
	 while(std::getline(ss, item, delim)) {
		 elems.push_back(item);
	 }
	 return elems;
 }


std::vector<std::string> split(const std::string &s, char delim) {
	 std::vector<std::string> elems;
	 return split(s, delim, elems);
 }

DBRegister* Console::parseRegister(std::string operation){
	using namespace std;

	size_t pos = operation.find_first_of(' ');

	if ( pos == string::npos) {
		std::cout<<"-- Error al parsear el comando"<<std::endl;
	}

	stringstream ss(operation.substr(pos));
    string item;
    vector<string> tokens;
    while(getline(ss, item, ':')) {
        tokens.push_back(item);
    }

	 if ( tokens.size() != 3 ) {
		 std::cout<<"-- Error al parsear el registro"<<std::endl;
		 return NULL;
	 }
	 return new DBRegister(tokens.at(0).c_str(),tokens.at(1).c_str(),tokens.at(2).c_str());

}

bool Console::quit(){
	return this->terminateExecution;
}



